﻿using System;
using System.Collections.Generic;
using Microsoft.Popfly.GameCreator.Collections;

namespace Microsoft.Popfly.GameCreator.GameEngine.Events
{
    public class CollisionClass
    {
        public enum SubType { ACTOR, ACTORINSTANCE, SOLID, NONSOLID, ALL };
        public SubType Type { get; protected set; }
        public string ActorOrInstance { get; protected set; }

        public CollisionClass(SubType subType, string actorOrInstance)
        {
            Type = subType;
            ActorOrInstance = actorOrInstance;
        }

        public CollisionClass(BehaviorOwner eventOwner, OrderedDictionary<String, Data.IncludeObjectInfo> includes, string subtype)
        {
            switch (subtype)
            {
                case "actor":
                    Type =  SubType.ACTOR;
                    if (includes.Count != 1)
                    {
                        throw new ArgumentException("Can't create a collision with an actor unless that actor's name is specified.");
                    }
                    ActorOrInstance = includes.getIndexedKey(0);
                    break;
                case "actorInstance":
                    Type = SubType.ACTORINSTANCE;
                    if (includes.Count != 1)
                    {
                        throw new ArgumentException("Can't create a collision with an actor instance unless that actor's name is specified.");
                    }
                    ActorOrInstance = includes.getIndexedKey(0);
                    break;
                case "self":
                    Type = SubType.ACTORINSTANCE;
                    ActorOrInstance = ((Actor)eventOwner).Name;
                    break;
                case "categories":
                    List<string> toRemove = new List<string>();
                    for (int i = 0; i < includes.Count; i++)
                    {                        
                        string key = includes.getIndexedKey(i);
                        if (key == "BulletsOther")
                        {
                            Console.Write("Removing category 'BulletsOther' since it is no longer valid.");
                            toRemove.Add(key);
                        }
                    }
                    foreach (string removeMe in toRemove)
                    {
                        includes.Remove(removeMe);
                    }

                    if (includes.Count == 1)
                    {
                        switch (includes.getIndexedKey(0))
                        {
                            case "Foreground":
                                Type = SubType.SOLID;
                                ActorOrInstance = null;
                                break;
                            case "Background":
                                Type = SubType.NONSOLID;
                                ActorOrInstance = null;
                                break;
                            default:
                                throw new ArgumentException("When subtype is categories, we don't understand '" +
                                    includes.getIndexedKey(0) +
                                    "'.");
                        }
                    }
                    else if (includes.Count == 2 &&
                             ((includes.getIndexedKey(0) == "Foreground" && includes.getIndexedKey(1) == "Background") ||
                              (includes.getIndexedKey(0) == "Background" && includes.getIndexedKey(1) == "Foreground")))
                    {
                        Type = SubType.ALL;
                        ActorOrInstance = null;
                    }
                    else
                    {
                        string categories = "";
                        for (int i = 0; i < includes.Count; i++)
                        {
                            categories += "\t" + includes.getIndexedKey(i) + "\n";
                        }
                        throw new NotImplementedException(
                            Utils.ErrorMessagePrefix +
                            "Don't understand this set of collision categories: \n{" + categories + "}\n");
                    }
                    break;
                default:
                    throw new ArgumentException(
                        Utils.ErrorMessagePrefix +
                        "CollisionListener does not know how to handle a collision subtype of '" +
                        subtype + "'."
                        );
            }
        }
    }
}
